home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Reference Guide / C-C++ Interactive Reference Guide.iso / c_ref / csource3 / 126_01 / martz_ad.c < prev    next >
Encoding:
Text File  |  1985-03-11  |  12.4 KB  |  461 lines

  1. /*********************************************************************\
  2. ** .---------------------------------------------------------------. **
  3. ** |                                                               | **
  4. ** |                                                               | **
  5. ** |         Copyright (c) 1981, 1982, 1983 by Eric Martz.         | **
  6. ** |                                                               | **
  7. ** |                                                               | **
  8. ** |       Permission is hereby granted to use this source         | **
  9. ** |       code only for non-profit purposes. Publication of       | **
  10. ** |       all or any part of this source code, as well as         | **
  11. ** |       use for business purposes is forbidden without          | **
  12. ** |       written permission of the author and copyright          | **
  13. ** |       holder:                                                 | **
  14. ** |                                                               | **
  15. ** |                          Eric Martz                           | **
  16. ** |                         POWER  TOOLS                          | **
  17. ** |                    48 Hunter's Hill Circle                    | **
  18. ** |                      Amherst MA 01002 USA                     | **
  19. ** |                                                               | **
  20. ** |                                                               | **
  21. ** `---------------------------------------------------------------' **
  22. \*********************************************************************/
  23.  
  24. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  25. /* MARTZLIB.C IS A LIBRARY OF FUNCTIONS OF GENERAL USE.
  26.  
  27.     MARTZ-AD.C CONTAINS:
  28.  
  29.         argmatch(match, &argc, argv, delete)
  30.         ati(n,s)
  31.         badname(name)
  32.         blankout(s,b)
  33.         charq(s,a)
  34.         checkint(s,i,buf,min,max,def)
  35.         chopwhite(side, buf)
  36.         copy(to, from, count)
  37.         delchars(start,stop,todelete)
  38.         dispchar(c)
  39.         dispexp(c, out);
  40. */
  41. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  42. char *argmatch(match, p_argc, argv, delete)
  43.  
  44. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  45.  
  46. /* CALL: string = argmatch(match, &argc, argv, delete);
  47.  
  48. RETURNS 0 IF NO ARGUMENT MATCHES match.
  49.  
  50. ELSE RETURNS THE STRING ADDRESS OF THE FIRST MATCHING ARGUMENT,
  51. AFTER DELETING (IF (delete)) REFERENCE TO THIS ARGUMENT IN argc, argv.
  52.  
  53. match CAN HAVE LEADING OR TRAILING AMBIGUITIES REPRESENTED AS *.
  54. * CANNOT BE IMBEDDED, NOR IS *X* PERMITTED.
  55.  
  56. EXAMPLES:
  57.  
  58.     if (arg = argmatch("-d*", &argc, argv, YES)) Debug = arg[1];
  59.     
  60.     if (name = argmatch("*.SS", &argc, argv, YES)) Fpin = fopen(name, "r");
  61.  
  62. */
  63. #define NONE 0
  64. #define LEAD 1
  65. #define TRAIL 2
  66.  
  67.     int *p_argc, delete;
  68.     char *match, **argv;
  69.     {
  70.     int i, ambig, mlen, hit;
  71.     char *arg;
  72.  
  73. /*
  74. printf("ARGMATCH\n");
  75. printf("match\"%s\"\n", match);
  76. printf("argc = %d\n", *p_argc);
  77. for (i=1; i< (*p_argc); i++) printf("\t\"%s\"\n", argv[i]);
  78. */
  79.     ambig = NONE;
  80.     
  81.     if (match[0] EQ '*') {
  82.         ambig = LEAD;
  83.         match++;
  84.     }
  85.     
  86.     if (match[strlen(match)-1] EQ '*') {
  87.         ambig = TRAIL;
  88.         match[strlen(match)-1] = NULL;
  89.     }
  90.     
  91.     mlen = strlen(match);
  92.     hit = NO;
  93.     
  94.     for (i=1; !hit AND i< (*p_argc) ; i++) {
  95.         switch(ambig) {
  96.  
  97.             case LEAD:
  98.                 if (equal(match, argv[i]+strlen(argv[i])-mlen))
  99.                     hit = i;
  100.                 break;
  101.  
  102.             case TRAIL:
  103.                 if(lefteq(match, argv[i]) EQ mlen) hit = i;
  104.                 break;
  105.  
  106.             default:
  107.                 if(equal(match, argv[i])) hit = i;
  108.         }
  109.     }
  110.     if (hit) {
  111.  
  112.         /* SAVE ARG */
  113.         arg = argv[hit];
  114.         
  115.         /* DELETE ARG */
  116.         if (delete) {
  117.             (*p_argc)--;
  118.             for (i=hit; i< (*p_argc) ; i++) argv[i] = argv[i+1];
  119.         }
  120.  
  121.         /* RETURN POINTER TO ARGUMENT FOUND */
  122.         return(arg);
  123.     }
  124.     else return(NO);
  125. }
  126. #undef NONE 0
  127. #undef LEAD 1
  128. #undef TRAIL 2
  129. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  130. ati(n,s)
  131.  
  132. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  133.  
  134. /* LOOKS FOR FIRST INTEGER IN STRING
  135. AFTER IGNORING LEADING BLANKS, TABS, AND ZEROS;
  136. IF FIRST NON-WHITE IS EOS OR NON-DIGIT,
  137. RETURNS -1; IF INTEGER EXCEEDS MAX,
  138. RETURNS +1. */
  139.  
  140.         int *n;
  141.         char *s;
  142.         {
  143.         int toobig, zer, eq, gr, m;
  144.         char max[6];
  145.         int i, sign;
  146.         toobig = zer = eq = gr = m = 0;
  147.         max[0]='\0';
  148.         strcat(max,"32767");
  149.         for (i=0; s[i]==' ' || s[i]=='\t'; i++)
  150.                 ; /* SKIP WHITE SPACE WITHIN LINE */
  151.         sign = 1;
  152.         if (s[i]=='+' || s[i]=='-')  /* SIGN */
  153.                 sign = (s[i++]=='+')? 1 : -1;
  154.         for (;s[i]=='0'; i++) zer = 1;
  155.                 /* SKIP ZEROS */
  156.         if (s[i]<'0' || s[i] >'9') {
  157.                 if (zer == 0) return(-1);
  158.                 else {
  159.                         *n = 0;
  160.                         return(0);
  161.                 }
  162.         }
  163.         for (*n=0; s[i]>='0' && s[i]<='9'; i++, m++) {
  164.                 if (m==5) return (1);
  165.                 if (s[i]>max[m]) gr += 1;
  166.                 if (s[i]==max[m]) eq += 1;
  167.                 if ((eq<(m+1)) && ((m+1) == (eq + gr))) toobig = 1;
  168.                 if ((toobig == 1) && (m == 4)) return (1);
  169.                 /* ABOVE 4 LINES DETECT INTEGERS >32767 */
  170.                 *n = (10 * *n) + (s[i] - '0');
  171.         }
  172.         *n = *n * sign;
  173.         return (0);
  174. }
  175. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  176. badname(dname)
  177.  
  178. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  179.  
  180. /* CHECKS FOR VALID CP/M FILENAME. RETURNS YES IF BAD, NO IF GOOD. */
  181. /* ISSUES DETAILED ERROR MESSAGE IF BAD. */
  182. /* THIS VERSION CHECKS FOR EMBEDDED SPACES */
  183.  
  184.     char *dname;
  185.     {
  186.     char left[16], right[32], name[32];
  187.     int len, count;
  188.  
  189.     strcpy(name, dname);
  190.     
  191.     /* DOES NAME CONTAIN AN IMBEDDED SPACE? */
  192.     if ((instr(0,name," ")) NE ERROR) goto bad;
  193.  
  194.     /* CHECK FOR : IN WRONG PLACE, OR TWO : */
  195.     count = freq(name, ":");
  196.     if (count >= 2) goto bad;
  197.     if (count EQ 1) {
  198.         if (name[1] NE ':') goto bad;
  199.         /* NO CHECKING FOR VALID DRIVE LETTER */
  200.         strcpy(name, name+2); /* DELETE DRIVE PREFIX */
  201.         if (!*name) goto bad;
  202.     }
  203.  
  204.     /* IS THE PREFIX TOO LONG > 8 ? */
  205.     strcpy(right, name);
  206.     len = todelim(left,right,".");
  207.     if (len EQ ERROR) {
  208.         strcpy(left,name);
  209.         len = strlen(left);
  210.         right[0] = NULL;
  211.     }
  212.     if (len > 8) {
  213. bad:
  214.         fprintf(STDERR,
  215. "Invalid CP/M file name:\"%s\"\n",name);
  216.         fprintf(STDERR,
  217. "Name must have not more than 8 characters before\n");
  218.         fprintf(STDERR,
  219. "and 3 after the period. It may not include a space or any of the\n");
  220.         fprintf(STDERR,
  221. "characters <>,;=[]. It may have only one '.' and only one ':'.\n");
  222.         fprintf(STDERR,
  223. "The ':', if any, must be the second character.\n");
  224.         return(1);
  225.     }
  226.     
  227.     /* IS NAME EMPTY, NAMELY "."? */
  228.     if (equal(name,".")) goto bad;
  229.  
  230.     /* A SECOND PERIOD IS BAD */
  231.     if (firstone(right,".")) goto bad;
  232.  
  233.     /* THE TYPE MAY NOT EXCEED 3 CHARACTERS */
  234.     if (strlen(right) > 3) goto bad;
  235.  
  236.     /* CHECK FOR BAD CHARACTERS */
  237.     if (firstone(dname,"<>,;=[]")) goto bad;
  238.  
  239.     /* ITS OK! */
  240.     return(0);
  241. }
  242. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  243. blankout(s,b)
  244.  
  245. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  246.  
  247. /* WITHIN STRING S, BLANKS OUT ALL CHARACTERS IN THE STRING B */ 
  248. /* Typical use: to blank out all acceptable delimiters (tab, ",",
  249.     newline, ";", etc.) so that blanks become the only delimiters
  250.     in a list of words/tokens/numbers. */
  251.  
  252.     char *s, *b;
  253.     {
  254.     int slen, blen, i, j;
  255.     slen = strlen(s);
  256.     blen = strlen(b);
  257.     for(i=0; i<slen; i++) {
  258.         for(j=0; j<blen; j++) {
  259.             if (s[i] == b[j]) {
  260.                 s[i] = ' ';
  261.                 break;
  262.             }
  263.         }
  264.     }
  265. }
  266. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  267. charq(s,a)
  268.  
  269. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  270.  
  271. /* Character question. Prints the string in "s" suffixed with a question mark,
  272. then obtains the first non-blank character from the input (discarding the
  273. remainder of the input line). If the character is contained in the string "a"
  274. (for answers), it is returned; else the question is reposed and another line
  275. of input is examined.
  276.  
  277. Example:
  278.  
  279.     answer = charq("Type of sort (numeric, alphabetic, mixed)","nam");    */
  280.  
  281.         char *s, *a;
  282.         {
  283.         char c;
  284.         int i, ok;
  285.         ok = 0;
  286.         while (!ok) {
  287.                 printf("%s?",s);
  288.                 leftc1(&c);
  289.                 i = strlen(a);
  290.                 while (i+1) if (c == a[i--]) ok = 1;
  291.         }
  292.         return(c);
  293. }
  294. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  295. checkint(s,i,buf,min,max,def)
  296.  
  297. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  298.  
  299. /* PRINTS THE MESSAGE s, THEN GETS A LINE FROM THE STANDARD INPUT
  300. AND ATTEMPTS TO CONVERT THE FIRST WORD TO AN INTEGER. REPEATS
  301. MESSAGE UNTIL A VALID INTEGER IS OBTAINED WITHIN THE RANGE min-max;
  302. THE VALUE OBTAINED IS ASSIGNED TO THE CONTENTS OF THE ADDRESS i.
  303. IF AN EMPTY LINE IS RETURNED, *i IS ASSIGNED THE DEFAULT VALUE def.
  304. RETURNS NOTHING.
  305. */
  306.     char *s, *buf;
  307.     int *i, min, max, def;
  308.     {
  309.     int check;
  310.     while (1) {
  311.         printf(s,def);
  312.         gets(buf);
  313.         if (!buf[0]) { /* EMPTY LINE: DEFAULT */
  314.             *i = def;
  315.             return(0);
  316.         }
  317.         check = ati(i,buf);
  318.         if (check < 0) {
  319.             printf("Integer not found.\n");
  320.             continue;
  321.         }
  322.         if (check > 0) {
  323.             printf("Invalid integer (outside +/- 32767).\n");
  324.             continue;
  325.         }
  326.         if (*i > max || *i < min) {
  327.             printf("Out of range.\n");
  328.             continue;
  329.         }
  330.         else return(0);
  331.     }
  332. }
  333. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  334. chopwhite(side, buf)
  335.  
  336. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  337.  
  338. /* CHOPS WHITESPACE (SPACES, TABS, NEWLINES) OFF SIDE ('r' RIGHT,
  339. 'l' LEFT, 'b' BOTH) */
  340.  
  341.     char side, *buf;
  342.     {
  343.     char *p;
  344.     if (side EQ 'r' OR side EQ 'b') {
  345.         p = buf;
  346.         while(*p) p++;
  347.         p--;
  348.         while (isspace(*p)) p--;
  349.         *(++p) = NULL;
  350.     }
  351.     if (side EQ 'l' OR side EQ 'b') {
  352.         p = buf;
  353.         while(isspace(*p)) p++;
  354.         if (p NE buf) while(*(buf++)=*(p++));
  355.     }
  356. }
  357. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  358. copy(to, from, count)
  359.  
  360. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  361.  
  362. /* COPIES count CHARACTERS FROM from TO to. NULLS HAVE NO EFFECT
  363. AND MAY BE COPIED. */
  364.  
  365.     char *to, *from;
  366.     {
  367.     int i;
  368.     for (i=0; i<= count-1; i++) to[i] = from[i];
  369. }
  370. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  371. delchars(start,stop,todelete)
  372.  
  373. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  374.  
  375. /* STARTING AT start, DELETES ALL CHARACTERS INCLUDED IN THE STRING todelete
  376. UP TO stop, OR IF stop IS 0, UP TO FIRST NULL. */
  377.  
  378.     char *start, *stop, *todelete;
  379.     {
  380.     char *p;
  381.     int delete, del_count;
  382.     del_count = 0;
  383.     if (stop EQ 0) stop = start + (strlen(start)) -1;
  384.     while (start <= stop) {
  385.         delete = NO;
  386.         for (p = todelete; *p; p++) {
  387.             if (*p EQ *start) delete = YES;
  388.             break;
  389.         }
  390.         if (delete) {
  391.             del_count++;
  392.             for (p = start; *p; p++)
  393.                 *p = *(p+1);
  394.             stop -= 1;
  395.             if (stop <start) return(del_count);
  396.         }
  397.         start++;
  398.     }
  399.     return(del_count);
  400. }
  401. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  402. dispchar(c)
  403.  
  404. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  405.  
  406. /* DISPLAYS ANY ASCII VALUE AS A PRINTABLE CHARACTER.
  407.  
  408.     FOR EXAMPLE, CONSIDER THAT WE WISH TO PRINT AN ASCII CHARACTER
  409.         WHICH HAS A DECIMAL VALUE OF d.
  410.  
  411.     ORDINARY PRINTABLE CHARACTERS ARE IN THE RANGE d=32-126 AND ARE
  412.         SIMPLY PRINTED.
  413.  
  414.     CONTROL CHARACTERS ARE IN THE RANGE d=0-31. THEY ARE PRINTED AS
  415.         '^' PLUS THE PRINTABLE CHARACTER d+64.
  416.  
  417.     DELETE/RUB OUT (d=127) IS PRINTED AS '^?', THAT IS ^(d-64).
  418.  
  419.     META CHARACTERS (THOSE WITH THE HIGH BIT SET, DECIMAL 128-255)
  420.         ARE PRINTED AS TILDE '~' PLUS d-128.
  421. */
  422.     int c;
  423.     {
  424.     char out[4];
  425.     dispexp(c, out);
  426.     puts(out);
  427. }
  428. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  429. dispexp(c, out)
  430.  
  431. /* Copyright (c) 1983 by Eric Martz, Amherst MA */
  432.  
  433. /* USED BY DISPCHAR */
  434.  
  435.     int c;
  436.     char *out;
  437.     {
  438.     char cs[2];
  439.     out[0] = NULL;
  440.     if (c > 126) {
  441.         if (c != 127) strcat(out, "~");
  442.         c -= 128;
  443.         if (c == -1 || c == 127) {
  444.             strcat(out, "^?");
  445.             return(0);
  446.         }
  447.     }
  448.     if (c <= 31) {
  449.         strcat(out, "^");
  450.         c += 64;
  451.     }
  452.     cs[0] = c;
  453.     cs[1] = NULL;
  454.     strcat(out, cs);
  455. }
  456. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  457. /*    END OF MARTZ-AD.C    */
  458. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
  459. NTED.
  460.  
  461.     CONTROL CHARACTERS ARE IN THE RANGE d=0-31. THEY ARE PRINTED AS